﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CoyoEden.Providers;

namespace CoyoEden.Models
{
	[Serializable]
	public class Community : BusinessBase<Community, int>, IComparable<Community>
	{
		#region .ctors
		/// <summary>
		/// Initializes a new instance of the <see cref="Category"/> class.
		/// </summary>
		public Community()
			: this("社区X", "我是一个社区，我用来组织用户们发表的话题")
		{
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="name"></param>
		/// <param name="description"></param>
		public Community(string name, string description)
		{
			this.Id = -1;
			this._Name = name;
			this._Description = description;
			this._Slug = "";
			this._Icon = NoIcon;
			this.Parent = -1;
		}

		#endregion

		#region Member variables
		public static readonly string NoIcon = "~/assets/img/unkown80x80.gif";
		private string _Name;
		public string Name
		{
			get { return _Name; }
			set
			{
				if (_Name != value)
				{
					MarkChanged("Name");
					_Name = value;
				}
			}
		}
		private string _Description;
		public string Description
		{
			get { return _Description; }
			set
			{
				if (_Description != value)
				{
					MarkChanged("Description");
					_Description = value;
				}
			}
		}
		private string _Icon;
		public string Icon
		{
			get { return string.IsNullOrEmpty(_Icon) ? NoIcon : _Icon; }
			set
			{
				if (_Icon != value)
				{
					MarkChanged("Icon");
					_Icon = value;
				}
			}
		}
		public string IconUrl
		{
			get
			{
				return Utils.ConvertToAbsolute(_Icon).ToString();
			}
		}
		private string _Slug;
		/// <summary>
		/// category slug
		/// </summary>
		public string Slug
		{
			get { return _Slug; }
			set
			{
				if (_Slug != value)
				{
					MarkChanged("Slug");
					_Slug = value;
				}
			}
		}
		private int _Parent;
		public int Parent
		{
			get
			{
				return _Parent;
			}
			set
			{
				if (_Parent != value)
					MarkChanged("Parent");
				_Parent = value;
			}
		}
		private static object _SyncRoot = new object();
		private static List<Community> _Communities;
		/// <summary>
		/// Gets an unsorted list of all Categories.
		/// </summary>
		public static List<Community> Communities
		{
			get
			{
				if (_Communities == null)
				{
					lock (_SyncRoot)
					{
						if (_Communities == null)
						{
							_Communities = PortalService.FillCommunities();
							_Communities.Sort();
						}
					}
				}

				return _Communities;
			}
		}
		#endregion

		#region BusinessBase Members
		protected override void ValidationRules()
		{
			AddRule("Name", "标题非法[标题不能为空并且必须具有唯一性]", NameRule());
			AddRule("Slug", "简称非法[简称具有必须唯一性]", SlugRule());
		}

		protected override Community DataSelect(int id)
		{
			return PortalService.SelectCommunity(id);
		}

		protected override void DataUpdate()
		{
			if (IsChanged)
				PortalService.UpdateCommunity(this);
		}

		protected override void DataInsert()
		{
			if (IsNew)
				PortalService.InsertCommunity(this);
		}

		protected override void DataDelete()
		{
			if (IsDeleted)
				PortalService.DeleteCommunity(this);

			if (Communities.Contains(this))
			{
				Communities.Remove(this);
			}
			Dispose();
		}
		public override string ToString()
		{
			return this.Name;
		}
		#endregion

		#region IComparable<Community> Members

		public int CompareTo(Community other)
		{
			return other.DateCreated.CompareTo(this.DateCreated);
		}

		#endregion

		#region helper methods
		/// <summary>
		/// Get Parent title
		/// </summary>
		/// <returns></returns>
		public string GetParentName()
		{
			if (_Parent < 0)
				return "";
			else
				return Community.GetCommunity(_Parent).Name;
		}
		/// <summary>
		/// Gets the full Name with Parent names included
		/// </summary>
		public string CompleteName()
		{
			if (_Parent <= 0)
				return _Name;
			else
			{
				string temp = GetCommunity(_Parent).CompleteName() + " - " + _Name;
				return temp;
			}
		}
		/// <summary>
		/// get children
		/// </summary>
		/// <returns></returns>
		public static List<Community> GetChildren(Community cc)
		{
			var children = from c in Communities
										 where c.Parent == cc.Id
										 select c;
			return children.ToList();
		}
		/// <summary>
		/// Returns a Community based on the specified id.
		/// </summary>
		public static Community GetCommunity(int id)
		{
			foreach (Community item in Communities)
			{
				if (item.Id == id)
					return item;
			}

			return null;
		}
		#endregion

		#region business rule

		/// <summary>
		/// 
		/// </summary>
		/// <returns>true means broken rule</returns>
		private bool NameRule()
		{
			var isRuleBroken = false;
			if (string.IsNullOrEmpty(_Name))
			{
				isRuleBroken = true;
				return isRuleBroken;
			}

			var item = Communities.Find(c => ((c.Name == _Name) && (c.Id != this.Id)));
			if (item != null)
			{
				isRuleBroken = true;
				return isRuleBroken;
			}
			return isRuleBroken;
		}
		private bool SlugRule()
		{
			bool isRuleBroken = false;
			if (string.IsNullOrEmpty(_Slug)) return isRuleBroken;
			//New category,validate slug
			if (!Utils.IsAlphaNumUnderline(_Slug)) return true;
			var cat = Communities.Find(c => ((c.Slug == _Slug) && (c.Id != this.Id)));
			if (cat != null)
			{
				isRuleBroken = true;
			}
			return isRuleBroken;
		}
		#endregion
	}
}
